<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><title>博客图片的 WebP 之路 | CC的部落格</title><meta name="author" content="CC康纳百川"><meta name="copyright" content="CC康纳百川"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="ffffff"><article data-clarity-region="article"></article><meta name="description" content="在主流浏览器都支持的情况下，我趁着文章还少，把所有文章的图片全部转换为 WebP 格式，以寻求更快的加载速度和丝滑的体验"><meta property="og:type" content="article"><meta property="og:title" content="博客图片的 WebP 之路"><meta property="og:url" content="https://blog.ccknbc.cc/posts/the-webp-road-of-blog-pictures/"><meta property="og:site_name" content="CC的部落格"><meta property="og:description" content="在主流浏览器都支持的情况下，我趁着文章还少，把所有文章的图片全部转换为 WebP 格式，以寻求更快的加载速度和丝滑的体验"><meta property="og:locale" content="zh_CN"><meta property="og:image" content="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/a4d78fbe1ca6e99e19535a095681c5ba_w1920_h1080_s770.jpg"><meta property="article:published_time" content="2020-11-29T08:38:36.000Z"><meta property="article:modified_time" content="2020-12-15T05:30:00.000Z"><meta property="article:author" content="CC康纳百川"><meta property="article:tag" content="博客"><meta name="twitter:card" content="summary"><meta name="twitter:image" content="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/a4d78fbe1ca6e99e19535a095681c5ba_w1920_h1080_s770.jpg"><link rel="shortcut icon" href="/favicon.ico"><link rel="canonical" href="https://blog.ccknbc.cc/posts/the-webp-road-of-blog-pictures/"><link rel="preconnect" href="https://jsd.cdn.zzko.cn"><link rel="preconnect" href="//static.cloudflareinsights.com"><link rel="preconnect" href="//www.clarity.ms"><link rel="preconnect" href="//busuanzi.ibruce.info"><link rel="preconnect" href="https://97MUPN4DMC-dsn.algolia.net" crossorigin=""><meta name="google-site-verification" content="tUkgeN6Ih2ArWtjw47oNSSl4Af2_MWjiKLrzZptUCdM"><meta name="msvalidate.01" content="71ADBCC80D679CEA8080BAFDCD54E368"><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@fortawesome/fontawesome-free/css/all.min.css"><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/node-snackbar/dist/snackbar.min.css" media="print" onload='this.media="all"'><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@fancyapps/ui/dist/fancybox/fancybox.css" media="print" onload='this.media="all"'><script>(()=>{const t={set:(e,t,a)=>{var o;0!==a&&(o=Date.now(),localStorage.setItem(e,JSON.stringify({value:t,expiry:o+864e5*a})))},get:e=>{var t=localStorage.getItem(e);if(t){t=JSON.parse(t);if(!(Date.now()>t.expiry))return t.value;localStorage.removeItem(e)}}},a=(window.btf={saveToLocal:t,getScript:(o,n={})=>new Promise((t,e)=>{const a=document.createElement("script");a.src=o,a.async=!0,a.onerror=e,a.onload=a.onreadystatechange=function(){var e=this.readyState;e&&"loaded"!==e&&"complete"!==e||(a.onload=a.onreadystatechange=null,t())},Object.keys(n).forEach(e=>{a.setAttribute(e,n[e])}),document.head.appendChild(a)}),getCSS:(o,n=!1)=>new Promise((t,e)=>{const a=document.createElement("link");a.rel="stylesheet",a.href=o,n&&(a.id=n),a.onerror=e,a.onload=a.onreadystatechange=function(){var e=this.readyState;e&&"loaded"!==e&&"complete"!==e||(a.onload=a.onreadystatechange=null,t())},document.head.appendChild(a)}),addGlobalFn:(e,t,a=!1,o=window)=>{var n=o.globalFn||{},d=n[e]||{};a&&d[a]||(d[a=a||Object.keys(d).length]=t,n[e]=d,o.globalFn=n)}},()=>{document.documentElement.setAttribute("data-theme","dark"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","#0d0d0d")}),o=()=>{document.documentElement.setAttribute("data-theme","light"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","ffffff")};btf.activateDarkMode=a,btf.activateLightMode=o;var e=t.get("theme"),n=window.matchMedia("(prefers-color-scheme: dark)").matches,d=window.matchMedia("(prefers-color-scheme: light)").matches,r=window.matchMedia("(prefers-color-scheme: no-preference)").matches,c=!n&&!d&&!r,n=(void 0===e?(d?o():n?a():(r||c)&&((d=(new Date).getHours())<=6||18<=d?a:o)(),window.matchMedia("(prefers-color-scheme: dark)").addListener(e=>{void 0===t.get("theme")&&(e.matches?a:o)()})):("light"===e?o:a)(),t.get("aside-status"));void 0!==n&&("hide"===n?document.documentElement.classList.add("hide-aside"):document.documentElement.classList.remove("hide-aside"));/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)&&document.documentElement.classList.add("apple")})()</script><script defer data-pjax="data-pjax" src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon="{&quot;token&quot;: &quot;35785b58f09f472ebfd7a2854973e6b8&quot;}"></script><script>!function(t,e,n,a,c,r){t[n]=t[n]||function(){(t[n].q=t[n].q||[]).push(arguments)},(c=e.createElement(a)).async=1,c.src="https://www.clarity.ms/tag/an4gdfm6a9",(r=e.getElementsByTagName(a)[0]).parentNode.insertBefore(c,r)}(window,document,"clarity","script")</script><script>const GLOBAL_CONFIG={postHeadAiDescription:{enable:!0,gptName:"CC",mode:"tianli",switchBtn:!0,btnLink:"https://tianli-blog.club/tianligpt/",randomNum:3,basicWordCount:1e3,key:"VCtoijR43E2uiVWkrZiC",Referer:"https://blog.ccknbc.cc/"},root:"/",algolia:void 0,localSearch:void 0,translate:{defaultEncoding:2,translateDelay:0,msgToTraditionalChinese:"繁",msgToSimplifiedChinese:"简"},noticeOutdate:{limitDay:15,position:"top",messagePrev:"本文最后一次更新为",messageNext:"天前，文章中的某些内容可能已过时！"},highlight:{plugin:"highlight.js",highlightCopy:!0,highlightLang:!0,highlightHeightLimit:!1,highlightFullpage:!0,highlightMacStyle:!0},copy:{success:"复制成功",error:"复制错误",noSupport:"浏览器不支持"},relativeDate:{homepage:!1,post:!1},runtime:"天",dateSuffix:{just:"刚刚",min:"分钟前",hour:"小时前",day:"天前",month:"个月前"},copyright:{limitCount:100,languages:{author:"作者: CC康纳百川",link:"链接: ",source:"来源: CC的部落格",info:"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},lightbox:"fancybox",Snackbar:{chs_to_cht:"你已切换为繁体中文",cht_to_chs:"你已切换为简体中文",day_to_night:"你已切换为深色模式",night_to_day:"你已切换为浅色模式",bgLight:"#49b1f5",bgDark:"#1f1f1f",position:"top-center"},infinitegrid:{js:"https://jsd.cdn.zzko.cn/npm/@egjs/infinitegrid/dist/infinitegrid.min.js",buttonText:"加载更多"},isPhotoFigcaption:!1,islazyload:!0,isAnchor:!1,percent:{toc:!0,rightside:!0},autoDarkmode:!0}</script><script id="config-diff">var GLOBAL_CONFIG_SITE={postAI:"在主流浏览器都支持的情况下，我趁着文章还少，把所有文章的图片全部转换为 WebP 格式，以寻求更快的加载速度和丝滑的体验",pageFillDescription:"WebP 转换, , WebP2jpg-online, , , , , 图床, , , , , , 自动化, 方案, 准备, PNG JPG GIF, 自动合并配置部分, 自动压缩配置部分, 自动转换配置部分, 视频（题外话）, , , , 关联阅读, CDN 解决方案博客图片的之路在主流浏览器都支持的情况下我趁着文章还少把所有文章的图片全部转换为格式以寻求更快的加载速度和丝滑的体验这篇文章同样有很多不完善的地方而且由于要写的比较详细的话可能需要很多截图而事实上这篇文章不会被太多人看到所以有需要再进行更新转换个人呢不喜欢为了这简单的事去下载一个专门的软件所以必定是找了很久在搜索引擎和论坛看评论以及综合个人使用经验推荐以下平台没广告做该做的事参数可调整智图又拍云到智图为什么推荐呢因为对于临时的一张图片用起来还是不错的而且图片品质参数可调个人按需以及实际情况做单张图片转换或者优化压缩可使用这个平台无需上传的图片转换器简单隐私快速官网是这么介绍的啦纯前端处理所以速度快慢取决于你的设备性能适合批量图片处理的情况同时多参数可调整处理完毕后会把所有文件打包压缩自动下载当然支持的格式不仅仅是名字那两种对于动态的处理个人用多张试了一下效果不是很理想不推荐如果处理过程中长时间进度卡着不动没办法刷新吧国内访问良好图片格式的发展趋势又拍云同时缺点吗就是不能快捷方便地选择图片质量右下角有调用方法但是改参数真的不方便啊而且我这边使用只能在控制台找报错图片地址然后新标签页打开保存处理好的动图也是只支持单张图片处理所以对于比较小的我还是推荐就用吧除非你和我封面一样几兆一张图必须得压缩不然博客访问速度可想而知同时浪费访客的流量到转换器这边测试呢确实是支持转换的但得到的图片比原图还大所以不怎么推荐但是还支持其他好多种格式转换所以还是很香的图床网上的那些知名图床好是好但就会偷偷删你文件所以黑人问号小众稳定的还是少不过备案了的话白嫖就很简单流浪图床鸡霸图床鸡霸网盘图王流浪图床以下文件托管支持了鸡霸图床单文件嗯鸡霸网盘以下文件托管支持了图床好吧大家用一个模板套出来的实际上就是利用微软的如果你也配置了话不如试试实际访问速度还是取决于当地运营商而他提供了游客图床的选项自己上传了拿到的链接比较好控制所以就没开但我没开启因为我用的云函数可按照教程配置即可支持一键部署自动化方案准备方案我的博客图床仓库这样写道本仓库文件使用上传其中图片使用压缩之后考虑加入转换作者貌似不考虑适配虽然测试成功了但是还是等等再说由压缩完成每天早晚点左右各执行一次压缩当然也可以手动点击压缩一次同时游客点击也会帮忙压缩一次谢谢图片上传完毕一会儿会由压缩提交然后由进行代码格式重置图片也不需要了其实最后由或自动合并比速度或由我打标签后由自动完成完成合并全部换成不需要自动压缩了虽然自动压缩是真的方便但还没完如果继续使用做图床做加速我面临以下问题将来图片越来越多仓库体积也会越来越大涉及到了的滥用问题万一哪天禁了或者关系到我账户使用问题后果很严重备份在哪将来统一更换链接方便有没有满足以下条件的图床稳定这是首要条件免费或者说够我这小型博客免费试用的量支持批量上传下载并且上传后文件名保持不变支持上传以配合实现流畅的写作体验相册功能要有批量多种场景不同格式链接以适应不同需求友好地支持格式包括动态访问速度还不错当然啦这么显得我是不是过于贪心了但真的没有一种比较好的解决方案对我这种不是优秀博主的人也可以很好的使用免费资源为博客图片加速呢我也在慢慢摸索中所以这篇博文会持续更新下去准备官网因为版本过多原因这里不放加速下载链接如果您访问过慢不如试试加速脚本或者加速插件这里提供我个人搭建的加速站您可以访问按照教程和说明下载关于配置如果要写的话肯定要截图这里放上别人的文章链接咯大家自行比对快速实现图床自动压缩使用也就是上面提到的图片上传完毕一会儿会由压缩提交按照要求选择免费计划授权完毕后勾选需要压缩图片的仓库即可但这就涉及到了是手动合并还是自动合并的选择问题如果你和我一样只要求压缩实际上当一遍又一遍的压缩优化推荐大家使用自动合并解决问题然后由进行代码格式重置图片也不需要了其实最后由或自动合并比速度或由我打标签后由自动完成完成合并如果是选择手动打标签完成合并即使用请前往安装并按照要求进行配置也就是在仓库启用后去编辑一下标签添加一个名为的标签而机器人提交了后我们打上这个标签便会自动执行合并操作之后将删除由创建的分支方便下次在进行自动压缩提交具体过程可通过下图查看别问我为什么不重新截图而我个人在建立博客的几个月中当然希望啥都能自动化啥都能免费白嫖省心最好因此选择了自动合并个人推荐使用因为它算是术业有专攻老牌子信得过功能强大关键是配置也比较简单易懂教程就不写了还是写了往下看跟着官方文档做就好谷歌页面翻译自动合并配置部分自动合并配置部分上面官方文档给出了三种创建配置文件的目录当然我是用第一种越懒越好直接根目录创建文件文件中的内容如下官方给出的例子其中包括了代码如下你如果没使用可以删掉那行仅满足提交人为这个条件即可即可刚才的截图告诉我们自动合并后将自动删除由它创建的分支所以这里我们无需额外配置我只是放在这里看看假如不会自动删除分支呢由于此种方式不是通过创建的而是通过新建分支所以必然需要删除无用的分支别担心这些都为你想到了官方文档这么写道实际上提供了自动删除分支选项你可以去配置里打开它如果以后在别的项目需要的话其他更多高级个性化配置可前往官方文档查看万一以后需要自动合并指定人提交的还有上面的开启打标签合并选项等操作再去配置相应的就行了所以推荐记住这个平台关于使用如果已经了解并比较熟练的掌握的话推荐使用别人编写好的你只要即可配置建议查看自动合并仓库详情可以去看但我建议自动合并的话两种方式选一种即可不然万一报错邮件是我们不希望看到的而这个也能实现上面一样的效果配置即可稍微复制粘贴照着配置即可教程网上也很多请自行查看或者直接查阅官方文档示例代码如下关于这个在前文中配置提到过用一样的即可我们在项目仓库中添加即可当然按照官方文档配置的话这个名字得叫在文档流里我们可以用做权限认证是一个默认存在的变量并不需要我们去添加不过要是跨仓库还是要使用手动生成的关于这点可以查看官方文档相关内容要实现自动合并提交的我的这么配置使用每天定时压缩这有个好处就是由于是本仓库文件所以省去了配置直接就行也比较省心同时图片压缩质量是通过调整参数可控的当然也可以再每次博客写完图片上传完毕后手动压缩一次达到可控效果毕竟我们并不希望上传一张照片自动压缩一次浪费资源哦自动压缩配置部分自动压缩配置部分我的这么配置的自己手动压缩一次游客帮忙手动压缩一次不用判断当然啦也可以部署到别的分支或者使用别人编写好的脚本来完成部署同时也可以设置一下环境变量时区改为上海但你们需要替换一下这部分内容因为没有安装依赖插件使用帮忙完成压缩同时根目录需要有来完成配置壓縮目錄內圖片類型預設取值範圍優化等級類型預設無失真壓縮圖片類型預設隔行掃描進行渲染類型預設多次優化直到完全優化输出到文件夹執行命令時執行的任務这种老的配置方法主要是任务执行时间比较短反正也是白嫖执行个一个小时也不为过那你可以替换为新版配置基础库图片压缩深度压缩移除的属性请不要无脑复制自行整合开启关闭需要的按照官方配置即可自动转换配置部分自动转换配置部分和自动压缩差不多但我们说了那是之前的解决方案现在我们是要让博客使用因此必须要向前看自动转换为同时链接后缀也得自动改或者手动改这我还在研究中其中图片使用压缩之后考虑加入转换作者貌似不考虑适配虽然测试成功了但是还是等等再说为什么这么说已经配置了我不想再配置少一个文件是一个文件还是用到了所以还是要装配置差不多用到的插件是配置如下至于怎么编写工作流文件你应该会了不过还是不能不考虑自己的插件那是真好用具体可查看官方如果是压缩安装插件配置文件写在文件里面说真的不错啊命令是但我们显然要转成具体配置如下效果比较好官方的话给了一个区间下面是转我还没本地测试不知道是否是能转成和差不多的动图而不是静态或者也可以去官方仓库看看别的插件配置用法反正我觉得本身还是挺好用的相比于这里是一个早期的例子现在有些已经过时安装依赖提示压缩率获取上传文件创建可读流获取上传文件扩展名根据扩展名设定媒体类型压缩图片文件名压缩源图片文件夹压缩目标文件夹压缩源图片路径压缩源图片绝对路径源文件夹绝对路径目标文件夹绝对路径创建可写流存储源图片可读流通过管道写入可写流删除图片压缩图片获取随机删除某一个包下面的需要符合格式的文件文件路径绝对路径需要删除的文件名称判断给定的路径是否存在返回文件和子目录的数组同步读取文件夹文件如果是文件夹则函数回调是指定文件则删除删除文件给定的路径不存在我们原来还在顾忌的支持问题考虑自适应加入判断又拍云也提供这样的功能但现在我的态度是你看不到我博客的图片是你我无缘视频题外话鸡霸网盘号鸡霸网盘号视频文件小于免审核预览当阿里这个免费的办公协同工具诞生我们在上传大文件视频进入播放页拿到调用地址即可不限速临时使用几天后地址会失效或许有大神蹲实际上就是利用微软的如果你也配置了话不如试试实际访问速度还是取决于当地运营商预览关联阅读中文文档性能优化图片优化让网站大小减少解决方案拿又拍云来说图像处理作图是个不错的解决方案",title:"博客图片的 WebP 之路",isPost:!0,isHome:!1,isHighlightShrink:!1,isToc:!0,postUpdate:"2020-12-15 13:30:00"}</script><script>"serviceWorker"in navigator&&(navigator.serviceWorker.register("/sw.js",{scope:"/"}).then(r=>{r.onupdatefound=()=>{const e=r.installing;e.onstatechange=()=>{"installed"===e.state&&(navigator.serviceWorker.controller?(void 0!==GLOBAL_CONFIG.Snackbar&&btf.snackbarShow("已刷新缓存，更新为最新内容"),navigator.serviceWorker.controller.postMessage({type:"skipWaiting"})):console.log("第一次注册Service Worker"))}}}),navigator.serviceWorker.addEventListener("message",e=>{e.data&&"refresh"===e.data.type&&(console.log("收到刷新页面请求，开始刷新页面"),window.location.reload())}))</script><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/hexo-butterfly-tag-plugins-plus/lib/assets/font-awesome-animation.min.css" media="defer" onload='this.media="all"'><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/hexo-butterfly-tag-plugins-plus/lib/tag_plugins.css" media="defer" onload='this.media="all"'><meta name="generator" content="Hexo 7.2.0"><link rel="alternate" href="/atom.xml" title="CC的部落格" type="application/atom+xml"><link rel="alternate" href="/rss.xml" title="CC的部落格" type="application/rss+xml"></head><body><script>window.paceOptions={restartOnPushState:!1},btf.addGlobalFn("pjaxSend",()=>{Pace.restart()},"pace_restart")</script><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/gh/CodeByZach/pace/themes/green/pace-theme-flash.css"><script src="https://jsd.cdn.zzko.cn/npm/pace-js/pace.min.js"></script><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/logo.png" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/404.jpg"' alt="avatar"></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">38</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">7</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">7</div></a></div><hr class="custom-hr"><div class="menus_items"><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-book-reader"></i><span> 文章</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fa-solid fa-box-archive"></i><span> 归档</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fa-solid fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fa-solid fa-folder-open"></i><span> 分类</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-cubes"></i><span> 社交</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/blogroll/"><i class="fa-fw fa-solid fa-link"></i><span> 友链</span></a></li><li><a class="site-page child" href="/moments/"><i class="fa-fw fa-solid fa-blog"></i><span> 友圈</span></a></li><li><a class="site-page child" href="/music/"><i class="fa-fw fa-solid fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/essay/"><i class="fa-fw fa-solid fa-comment-alt"></i><span> 短文</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-desktop"></i><span> 关于</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/sub/"><i class="fa-fw fa-solid fa-bell"></i><span> 订阅</span></a></li><li><a class="site-page child" href="/about/"><i class="fa-fw fa-solid fa-list-check"></i><span> 本站</span></a></li><li><a class="site-page child" href="/privacy-policy/"><i class="fa-fw fa-solid fa-user-secret"></i><span> 隐私</span></a></li><li><a class="site-page child" target="_blank" rel="noopener external nofollow noreferrer" href="https://cc.instatus.com"><i class="fa-fw fa-solid fa-server"></i><span> 状态</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image:url(https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/a4d78fbe1ca6e99e19535a095681c5ba_w1920_h1080_s770.jpg)"><nav id="nav"><span id="blog-info"><a href="/" title="CC的部落格"><span class="site-name">CC的部落格</span></a></span><div id="menus"><div id="search-button"><span class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></span></div><div class="menus_items"><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-book-reader"></i><span> 文章</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fa-solid fa-box-archive"></i><span> 归档</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fa-solid fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fa-solid fa-folder-open"></i><span> 分类</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-cubes"></i><span> 社交</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/blogroll/"><i class="fa-fw fa-solid fa-link"></i><span> 友链</span></a></li><li><a class="site-page child" href="/moments/"><i class="fa-fw fa-solid fa-blog"></i><span> 友圈</span></a></li><li><a class="site-page child" href="/music/"><i class="fa-fw fa-solid fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/essay/"><i class="fa-fw fa-solid fa-comment-alt"></i><span> 短文</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-desktop"></i><span> 关于</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/sub/"><i class="fa-fw fa-solid fa-bell"></i><span> 订阅</span></a></li><li><a class="site-page child" href="/about/"><i class="fa-fw fa-solid fa-list-check"></i><span> 本站</span></a></li><li><a class="site-page child" href="/privacy-policy/"><i class="fa-fw fa-solid fa-user-secret"></i><span> 隐私</span></a></li><li><a class="site-page child" target="_blank" rel="noopener external nofollow noreferrer" href="https://cc.instatus.com"><i class="fa-fw fa-solid fa-server"></i><span> 状态</span></a></li></ul></div></div><div id="toggle-menu"><span class="site-page"><i class="fas fa-bars fa-fw"></i></span></div></div></nav><div id="post-info"><h1 class="post-title">博客图片的 WebP 之路</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-11-29T08:38:36.000Z" title="发表于 2020-11-29 16:38:36">2020-11-29</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2020-12-15T05:30:00.000Z" title="更新于 2020-12-15 13:30:00">2020-12-15</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E5%8D%9A%E5%AE%A2/">博客</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">5.2k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>20分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" data-flag-title="博客图片的 WebP 之路"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><div class="post-ai-description"><div class="ai-title"><i class="fa-solid fa-newspaper"></i><div class="ai-title-text">AI-摘要</div><div id="ai-Toggle" title="CC/Tianli 模式切换">切换</div><i class="fa-solid fa-podcast" title="Tianli 模式下朗读摘要"></i><i class="fa-solid fa-arrow-rotate-right" title="Tianli 模式下刷新摘要"></i><div id="ai-tag">Tianli GPT</div></div><div class="ai-explanation">AI初始化中...</div><div class="ai-btn-box"><div class="ai-btn-item">介绍自己 🙈</div><div class="ai-btn-item">生成摘要 👋</div><div class="ai-btn-item">相关推荐 📖</div><div class="ai-btn-item">前往主页 🏠</div><div class="ai-btn-item" id="go-tianli-blog">前往爱发电购买</div></div><script data-pjax src="/"></script></div><article class="post-content" id="article-container"><p><a href="https://blog.ccknbc.cc/posts/the-webp-road-of-blog-pictures/">博客图片的 WebP 之路</a>在主流浏览器都支持的情况下，我趁着文章还少，把所有文章的图片全部转换为 WebP 格式，以寻求更快的加载速度和丝滑的体验</p><div class="note warning flat"><p>这篇文章同样有很多不完善的地方，而且由于要写的比较详细的话，可能需要很多截图，而事实上这篇文章不会被太多人看到，所以有需要再进行更新</p></div><h2 id="WebP-转换">WebP 转换<a class="fa-solid fa-hashtag" href="#WebP-转换"></a></h2><p>个人呢，不喜欢为了这简单的事去下载一个专门的软件，所以必定是找了很久，在搜索引擎和论坛看评论，以及综合个人使用经验，推荐以下平台</p><ul><li>没广告，做该做的事</li><li>参数可调整</li></ul><div class="tabs" id="webp转换"><ul class="nav-tabs no-default"><button type="button" class="tab" data-href="webp转换-1">智图</button><button type="button" class="tab" data-href="webp转换-2">WebP2jpg-online</button><button type="button" class="tab" data-href="webp转换-3">又拍云</button><button type="button" class="tab" data-href="webp转换-4">GIF到WebP</button></ul><div class="tab-contents"><div class="tab-item-content" id="webp转换-1"><h3 id="智图"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://zhitu.isux.us/">智图</a><a class="fa-solid fa-hashtag" href="#智图"></a></h3><p>为什么推荐呢，因为对于临时的一张图片用起来还是不错的，而且图片品质参数可调，个人按需以及实际情况做单张图片转换或者优化压缩可使用这个平台</p></div><div class="tab-item-content" id="webp转换-2"><h3 id="WebP2jpg-online">WebP2jpg-online<a class="fa-solid fa-hashtag" href="#WebP2jpg-online"></a></h3><p>「无需上传的图片转换器-简单、隐私、快速」官网是这么介绍的啦，纯前端处理，所以速度快慢取决于你的设备性能，适合批量图片处理的情况，同时多参数可调整，处理完毕后会把所有文件打包压缩自动下载，当然支持的格式不仅仅是名字那两种</p><div class="note info flat"><p>对于 WebP 动态的处理，个人用多张 gif 试了一下，效果不是很理想，不推荐</p></div><div class="note warning flat"><p>如果处理过程中，长时间进度卡着不动，没办法，刷新吧</p></div><h4 id="Gitee-Pages（国内访问良好）"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://renzhezhilu.gitee.io/WebP2jpg-online/">Gitee Pages（国内访问良好）</a><a class="fa-solid fa-hashtag" href="#Gitee-Pages（国内访问良好）"></a></h4><h4 id="GitHub-Pages"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://renzhezhilu.github.io/WebP2jpg-online/">GitHub Pages</a><a class="fa-solid fa-hashtag" href="#GitHub-Pages"></a></h4></div><div class="tab-item-content" id="webp转换-3"><h3 id="WebP-图片格式的发展趋势-又拍云"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.upyun.com/WebP">WebP - 图片格式的发展趋势 - 又拍云</a><a class="fa-solid fa-hashtag" href="#WebP-图片格式的发展趋势-又拍云"></a></h3><p>同时缺点吗就是不能快捷方便地选择图片质量（右下角有 api 调用方法，但是改参数真的不方便啊），而且我这边使用只能在控制台<code>Console</code>找报错图片地址，然后新标签页打开保存处理好的<code>WebP</code>动图，也是只支持单张图片处理，所以对于比较小的<code>gif</code>我还是推荐就用<code>gif</code>吧，除非你和我封面一样，几兆一张图必须得压缩，不然博客访问速度可想而知，同时浪费访客的流量</p></div><div class="tab-item-content" id="webp转换-4"><h3 id="GIF-到-WEBP-转换器"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://convertio.co/zh/gif-webp/">GIF 到 WEBP 转换器</a><a class="fa-solid fa-hashtag" href="#GIF-到-WEBP-转换器"></a></h3><p>这边测试呢，确实是支持转换的，但得到的图片比原图还大，所以不怎么推荐，但是还支持其他好多种格式转换，所以还是很香的</p></div></div><div class="tab-to-top"><button type="button" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div><h2 id="图床">图床<a class="fa-solid fa-hashtag" href="#图床"></a></h2><p>网上的那些知名图床好是好，但就会偷偷删你文件，所以黑人问号，小众稳定的还是少不过备案了的话白嫖就很简单</p><div class="tabs" id="图床"><ul class="nav-tabs no-default"><button type="button" class="tab" data-href="图床-1">流浪图床</button><button type="button" class="tab" data-href="图床-2">鸡霸图床</button><button type="button" class="tab" data-href="图床-3">鸡霸网盘</button><button type="button" class="tab" data-href="图床-4">图王</button><button type="button" class="tab" data-href="图床-5">OneManager</button></ul><div class="tab-contents"><div class="tab-item-content" id="图床-1"><h3 id="流浪图床"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://p.sda1.dev/">流浪图床</a><a class="fa-solid fa-hashtag" href="#流浪图床"></a></h3><p>5M 以下文件托管，支持了 WebP，api</p></div><div class="tab-item-content" id="图床-2"><h3 id="鸡霸图床"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://img.gejiba.com/">鸡霸图床</a><a class="fa-solid fa-hashtag" href="#鸡霸图床"></a></h3><p>10M 单文件，嗯</p></div><div class="tab-item-content" id="图床-3"><h3 id="鸡霸网盘"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://gejiba.com/upload.php">鸡霸网盘</a><a class="fa-solid fa-hashtag" href="#鸡霸网盘"></a></h3><p>30M 以下文件托管，支持了 WebP</p></div><div class="tab-item-content" id="图床-4"><h3 id="IMG-WANG"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://img.wang/">IMG.WANG</a><a class="fa-solid fa-hashtag" href="#IMG-WANG"></a></h3><p>图床，好吧大家用一个模板套出来的</p></div><div class="tab-item-content" id="图床-5"><h3 id="OneManager"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/qkqpttgf/OneManager-php">OneManager</a><a class="fa-solid fa-hashtag" href="#OneManager"></a></h3><p>实际上就是利用微软的 OneDrive，如果你也配置了话，不如试试，实际访问速度还是取决于当地运营商，而他提供了游客图床的选项（自己上传了拿到的链接比较好控制，所以就没开），但我没开启（因为我用的云函数），可按照教程配置即可，支持 heroku 一键部署</p></div></div><div class="tab-to-top"><button type="button" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div><h2 id="自动化">自动化<a class="fa-solid fa-hashtag" href="#自动化"></a></h2><div class="tabs" id="自动化"><ul class="nav-tabs no-default"><button type="button" class="tab" data-href="自动化-1">方案</button><button type="button" class="tab" data-href="自动化-2">准备</button><button type="button" class="tab" data-href="自动化-3">PNG JPG GIF</button></ul><div class="tab-contents"><div class="tab-item-content" id="自动化-1"><h3 id="方案">方案<a class="fa-solid fa-hashtag" href="#方案"></a></h3><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/ccknbc-backup/photos/">我的博客图床仓库</a><code>README</code>这样写道</p><ul><li>本仓库文件使用<code>PicGo</code>上传</li><li>其中图片使用<code>gulp imagemin</code>压缩</li><li>（之后考虑加入<code>WebP</code>转换 👍，<code>gulp</code>作者貌似不考虑适配，虽然<code>imagemin</code>测试成功了，但是还是等等再说）</li><li>由<code>GitHub Actions</code>压缩完成</li><li>每天早晚 8 点左右各执行一次压缩</li><li>当然也可以手动点击压缩一次</li><li>同时游客点击<code>Star</code>也会帮忙压缩一次（谢谢）</li><li>图片上传完毕一会儿会由<code>Imgbot</code>压缩提交<code>PR</code></li><li>然后由<code>Restyled</code>进行代码格式重置（图片也不需要了其实）</li><li>最后由<code>Mergify</code>或<code>Github Actions</code>自动合并<code>PR</code>（比速度 🚀）</li><li>(或由我打标签后由<code>PRValet</code>自动完成完成<code>PR</code>合并）</li></ul><p>全部换成<code>WebP</code>，不需要自动压缩了，虽然自动压缩是真的方便</p><p>但还没完，如果继续使用<code>GitHub</code>做图床，<code>jsDelivr</code>做<code>CDN</code>加速，我面临以下问题</p><ul><li>将来图片越来越多，仓库体积也会越来越大</li><li>涉及到了 jsd 的滥用问题，万一哪天禁了，或者关系到我<code>GitHub</code>账户使用问题，后果很严重</li><li>备份在哪，将来统一更换链接方便，有没有满足以下条件的图床</li></ul><ol><li>稳定，这是首要条件</li><li>免费，或者说够我这小型博客免费试用的量</li><li>支持批量上传下载，并且上传后文件名保持不变</li><li>支持<code>API</code>上传，以配合<code>PicGo</code>实现流畅的写作体验</li><li>相册功能要有，批量多种场景不同格式链接以适应不同需求</li><li>友好地支持 WebP 格式（包括动态）</li><li>访问速度还不错 …</li></ol><p>当然啦，这么显得我是不是过于贪心了，但真的没有一种比较好的解决方案，对我这种不是优秀博主的人也可以很好的使用免费资源为博客图片加速呢？</p><p><code>A:</code>我也在慢慢摸索中，所以这篇博文会持续更新下去</p></div><div class="tab-item-content" id="自动化-2"><h3 id="准备">准备<a class="fa-solid fa-hashtag" href="#准备"></a></h3><ol><li><a target="_blank" rel="noopener external nofollow noreferrer" href="https://molunerfinn.com/PicGo/">PicGo 官网</a>因为版本过多原因，这里不放加速下载链接，如果您访问过慢，不如试试加速脚本或者加速插件这里提供我个人搭建的加速站，您可以<a target="_blank" rel="noopener external nofollow noreferrer" href="https://gh.ccknbc.workers.dev/">访问按照教程和说明下载</a></li><li>关于配置如果要写的话肯定要截图，这里放上别人的文章链接咯，大家自行比对 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://blog.juanertu.com/archives/adff04af.html">PicGo+GitHub 快速实现 markdown 图床</a></li><li>自动压缩<ol><li>使用<code>GitHub APP</code>，也就是上面提到的<ul><li>图片上传完毕一会儿会由<code>Imgbot</code>压缩提交<code>PR</code></li></ul></li><li><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/marketplace/imgbot">ImgBot</a> optimizes your images and saves you time.</li></ol><ul><li>按照要求选择免费计划，授权完毕后勾选需要压缩图片的仓库即可但这就涉及到了是手动合并 PR 还是自动合并 PR 的选择问题，如果你和我一样只要求压缩，实际上当一遍又一遍的压缩优化，推荐大家使用自动合并 PR 解决问题 - 然后由<code>Restyled</code>进行代码格式重置（图片也不需要了其实） - 最后由<code>Mergify</code>或<code>Github Actions</code>自动合并<code>PR</code>（比速度 🚀） - (或由我打标签后由<code>PRValet</code>自动完成完成<code>PR</code>合并）</li></ul></li></ol></div><div class="tab-item-content" id="自动化-3"><h3 id="PNG-JPG-GIF">PNG JPG GIF<a class="fa-solid fa-hashtag" href="#PNG-JPG-GIF"></a></h3><div class="note info icon flat"><p>如果是选择手动打标签完成合并，即使用<code>PRValet</code>，请<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/marketplace/pr-valet">前往安装</a>，并按照要求进行配置</p><p>How to use PR Valet</p><ol><li>Step 1: Install <a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/marketplace/pr-valet">PR Valet</a>.</li><li>Step 2: Add the <code>valet:merge</code> label to your pull request.</li><li>Step 3: Work on your other tasks while PR Valet takes care of merging your pull request.</li></ol><p>也就是在仓库启用后，去编辑一下 label 标签，添加一个名为<code>valet:merge</code>的标签，而机器人提交了 PR 后，我们打上这个标签，便会自动执行合并操作，之后 imgbot 将删除由<code>imgbot</code>创建的分支 imgbot，方便下次在进行自动压缩，提交 PR</p><p>具体过程可通过下图查看（别问我为什么不重新截图）</p><p><img src= "" data-lazy-src="https://cdn.nlark.com/yuque/0/2020/png/8391407/1608792470422-d8276572-96b4-4b3b-9e7b-dfee414b9f5e.png#height=997&amp;id=OFjp7&amp;originHeight=997&amp;originWidth=1156&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;size=0&amp;status=done&amp;style=none&amp;title=&amp;width=1156" alt="" loading="lazy"></p></div><p>而我个人在建立博客的几个月中，当然希望啥都能自动化，啥都能免费白嫖，省心最好，因此选择了自动合并</p><p>个人推荐使用<code>mergify</code>，因为它算是术业有专攻，老牌子信得过，功能强大，关键是配置也比较简单易懂</p><p>教程就不写了（还是写了，往下看），跟着<a target="_blank" rel="noopener external nofollow noreferrer" href="https://docs.mergify.io/">官方文档</a>做就好（谷歌 Chrome 页面翻译？</p></div></div><div class="tab-to-top"><button type="button" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div><details class="folding-tag" yellow><summary>自动合并配置部分</summary><div class="content"><h3 id="自动合并配置部分">自动合并配置部分<a class="fa-solid fa-hashtag" href="#自动合并配置部分"></a></h3><p>The Configuration File</p><p>Mergify applies rules to your pull requests. To do that, you need to create a Mergify configuration in each repository where Mergify is used.</p><p>The configuration file should be created in the root directory of the repository and named either <code>.mergify.yml</code> or <code>.mergify/config.yml</code> or <code>.github/mergify.yml</code>.</p><p>As the file name implies, the configuration file format is based on <a target="_blank" rel="noopener external nofollow noreferrer" href="https://yaml.org/">YAML</a>, a simplistic file format for data. The configuration file format is entirely documented in <a target="_blank" rel="noopener external nofollow noreferrer" href="https://docs.mergify.io/configuration.html#configuration-file-format">🔖 Configuration File</a>.</p><p>上面官方文档给出了三种创建配置文件的目录，当然我是用第一种（越懒越好）直接根目录创建<code>.mergify.yml</code>文件，文件中的内容如下</p><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://docs.mergify.io/examples.html#bots">mergify 官方给出的例子</a>其中包括了 imgbot，代码如下</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">pull_request_rules:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">automatic</span> <span class="string">merge</span> <span class="string">for</span> <span class="string">ImgBot</span> <span class="string">pull</span> <span class="string">requests</span></span><br><span class="line">    <span class="attr">conditions:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">author=imgbot[bot]</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">check-success=Travis</span> <span class="string">CI</span> <span class="bullet">-</span> <span class="string">Pull</span> <span class="string">Request</span></span><br><span class="line">    <span class="attr">actions:</span></span><br><span class="line">      <span class="attr">merge:</span></span><br><span class="line">        <span class="attr">method:</span> <span class="string">merge</span></span><br></pre></td></tr></table></figure><p>你如果没使用 Travis CI，可以删掉那行，仅满足提交人为 imgbot 这个条件即可即可</p><p>刚才的截图告诉我们，自动合并后,imgbot 将自动删除由它创建的<code>imgbot</code>分支，所以这里我们无需额外配置，我只是放在这里看看，假如 imgbot 不会自动删除分支呢</p><p>由于此种方式不是通过 fork 创建的 pr，而是通过新建分支，所以必然需要删除无用的分支，别担心，这些都为你想到了，官方文档这么写道</p><p>Some users create pull request from the same repository by using different branches — rather than creating a pull request from a fork. That’s fine, but it tends to leave a lot of useless branch behind when the pull request is merged.</p><p>Mergify allows to delete those branches once the pull request has been merged:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">pull_request_rules:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">delete</span> <span class="string">head</span> <span class="string">branch</span> <span class="string">after</span> <span class="string">merge</span></span><br><span class="line">    <span class="attr">conditions:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">merged</span></span><br><span class="line">    <span class="attr">actions:</span></span><br><span class="line">      <span class="attr">delete_head_branch:</span> &#123;&#125;</span><br></pre></td></tr></table></figure><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/managing-the-automatic-deletion-of-branches">实际上 Github 提供了自动删除分支选项</a>，你可以去配置里打开它（如果以后在别的项目需要的话</p><p>其他更多高级个性化配置可前往<a target="_blank" rel="noopener external nofollow noreferrer" href="https://docs.mergify.io/">官方文档</a>查看，万一以后需要自动合并指定人提交的 PR，还有上面的开启打标签合并选项等操作，再去配置相应的就行了（所以推荐记住这个平台）</p><p>关于使用 Actions，如果已经了解并比较熟练的掌握的话推荐使用别人编写好的 actions,你只要 use 即可，配置建议查看<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/pascalgn/automerge-action">自动合并 PR Actions 仓库</a>，详情可以去看 README，但我建议自动合并 PR 的话两种方式选一种即可，不然万一报错邮件是我们不希望看到的而这个 actions 也能实现上面一样的效果，配置<code>MERGE_FILTER_AUTHOR</code>即可: When set, only pull requests raised by this author will be merged automatically.稍微复制粘贴，照着 README 配置即可，actions 教程网上也很多，请自行查看，或者直接查阅<a target="_blank" rel="noopener external nofollow noreferrer" href="https://docs.github.com/en/free-pro-team@latest/actions">官方文档</a></p><p>README 示例代码如下</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">automerge</span></span><br><span class="line"><span class="attr">on:</span></span><br><span class="line">  <span class="attr">pull_request:</span></span><br><span class="line">    <span class="attr">types:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">labeled</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">unlabeled</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">synchronize</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">opened</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">edited</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">ready_for_review</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">reopened</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">unlocked</span></span><br><span class="line">  <span class="attr">pull_request_review:</span></span><br><span class="line">    <span class="attr">types:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">submitted</span></span><br><span class="line">  <span class="attr">check_suite:</span></span><br><span class="line">    <span class="attr">types:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">completed</span></span><br><span class="line">  <span class="attr">status:</span> &#123;&#125;</span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line">  <span class="attr">automerge:</span></span><br><span class="line">    <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line">    <span class="attr">steps:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">automerge</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">&quot;pascalgn/automerge-action@v0.12.0&quot;</span></span><br><span class="line">        <span class="attr">env:</span></span><br><span class="line">          <span class="attr">GITHUB_TOKEN:</span> <span class="string">&quot;$<span class="template-variable">&#123;&#123; secrets.GITHUB_TOKEN &#125;&#125;</span>&quot;</span></span><br></pre></td></tr></table></figure><p>关于这个<code>GITHUB_TOKEN</code>，在前文中配置 Picgo 提到过，用一样的即可，我们在项目仓库中添加 secrets 即可，当然按照官方文档配置的话，这个名字得叫<code>GITHUB_TOKEN</code></p><div class="note info icon flat"><p>在 workflow 文档流里我们可以用<code>${{ secrets.GITHUB_TOKEN }}</code>做权限认证，是一个默认存在的变量，并不需要我们去添加 ACCESS_TOKEN，不过要是跨仓库还是要使用手动生成的 TOKEN，<a target="_blank" rel="noopener external nofollow noreferrer" href="https://docs.github.com/en/free-pro-team@latest/actions/reference/authentication-in-a-workflow#about-the-github_token-secret">关于这点，可以查看官方文档相关内容</a></p></div><p>要实现自动合并 imgbot 提交的 PR，我的 workflow 这么配置</p><p>使用<code>GitHub Actions</code>，每天定时压缩</p><p>这有个好处就是由于是本仓库文件，所以省去了<code>Secrects</code>配置，直接 push 就行，也比较省心，同时图片压缩质量是通过调整参数可控的，当然也可以再每次博客写完，图片上传完毕后手动压缩一次，达到可控效果，毕竟我们并不希望上传一张照片自动压缩一次，浪费资源哦</p></div></details><details class="folding-tag" blue><summary>自动压缩配置部分</summary><div class="content"><h3 id="自动压缩配置部分">自动压缩配置部分<a class="fa-solid fa-hashtag" href="#自动压缩配置部分"></a></h3><p>我的 workflow 这么配置的</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">Compress</span> <span class="string">Image</span></span><br><span class="line"></span><br><span class="line"><span class="attr">on:</span></span><br><span class="line">  <span class="attr">schedule:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">cron:</span> <span class="string">&quot;0 0,12 * * *&quot;</span></span><br><span class="line">  <span class="attr">workflow_dispatch:</span></span><br><span class="line">    <span class="attr">inputs:</span></span><br><span class="line">      <span class="attr">name:</span></span><br><span class="line">        <span class="attr">description:</span> <span class="string">&quot;自己手动压缩一次&quot;</span></span><br><span class="line">        <span class="attr">required:</span> <span class="literal">false</span></span><br><span class="line">  <span class="attr">watch:</span></span><br><span class="line">    <span class="attr">types:</span> [<span class="string">started</span>] <span class="comment">#游客帮忙手动压缩一次，不用判断</span></span><br><span class="line"></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line">  <span class="attr">deploy:</span></span><br><span class="line">    <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line"></span><br><span class="line">    <span class="attr">steps:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Checkout</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/checkout@v2</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">ref:</span> <span class="string">master</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Setup</span> <span class="string">Node</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/setup-node@v2-beta</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">node-version:</span> <span class="string">&quot;12.x&quot;</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Catch</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/cache@v2</span></span><br><span class="line">        <span class="attr">id:</span> <span class="string">cache-dependencies</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">path:</span> <span class="string">node_modules</span></span><br><span class="line">          <span class="attr">key:</span> <span class="string">$&#123;&#123;runner.OS&#125;&#125;-$&#123;&#123;hashFiles(&#x27;**/package-lock.json&#x27;)&#125;&#125;</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">Dependencies</span></span><br><span class="line">        <span class="attr">if:</span> <span class="string">steps.cache-dependencies.outputs.cache-hit</span> <span class="type">!=</span> <span class="string">&#x27;true&#x27;</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          npm install</span></span><br><span class="line"><span class="string"></span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Compress</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          gulp</span></span><br><span class="line"><span class="string"></span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          git config --global user.name &quot;github-actions[bot]&quot;</span></span><br><span class="line"><span class="string">          git config --global user.email &quot;github-actions[bot]@users.noreply.github.com&quot;</span></span><br><span class="line"><span class="string">          git init</span></span><br><span class="line"><span class="string">          git add -A</span></span><br><span class="line"><span class="string">          git commit -m &quot;$(date +&quot;%Z %Y-%m-%d %A %H:%M:%S&quot;) Updated By Github Actions&quot;</span></span><br><span class="line"><span class="string">          git push</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="comment"># 当然啦也可以部署到别的分支，或者使用别人编写好的脚本来完成部署，同时也可以设置一下环境变量时区改为上海</span></span><br></pre></td></tr></table></figure><p>但你们需要替换一下这部分内容（因为没有<code>package.json</code>）</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">Dependencies</span></span><br><span class="line">      <span class="attr">if:</span> <span class="string">steps.cache-dependencies.outputs.cache-hit</span> <span class="type">!=</span> <span class="string">&#x27;true&#x27;</span></span><br><span class="line">      <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">        npm install gulp gulp-imagemin</span></span><br><span class="line"><span class="string"></span><span class="string">//安装依赖，插件，使用gulp帮忙完成压缩</span></span><br></pre></td></tr></table></figure><p>同时根目录需要有<code>gulpfile.js</code>，来完成配置</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> gulp = <span class="built_in">require</span>(<span class="string">&quot;gulp&quot;</span>);</span><br><span class="line"><span class="keyword">var</span> imagemin = <span class="built_in">require</span>(<span class="string">&quot;gulp-imagemin&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 壓縮 public/uploads 目錄內圖片</span></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&quot;minify-images&quot;</span>, <span class="keyword">async</span> () =&gt; &#123;</span><br><span class="line">  gulp</span><br><span class="line">    .<span class="title function_">src</span>(<span class="string">&quot;.public/uploads/**/*.*&quot;</span>)</span><br><span class="line">    .<span class="title function_">pipe</span>(</span><br><span class="line">      <span class="title function_">imagemin</span>(&#123;</span><br><span class="line">        <span class="attr">optimizationLevel</span>: <span class="number">7</span>, <span class="comment">// 類型：Number  預設：3  取值範圍：0-7（優化等級）</span></span><br><span class="line">        <span class="attr">progressive</span>: <span class="literal">true</span>, <span class="comment">// 類型：Boolean 預設：false 無失真壓縮jpg圖片</span></span><br><span class="line">        <span class="attr">interlaced</span>: <span class="literal">true</span>, <span class="comment">// 類型：Boolean 預設：false 隔行掃描gif進行渲染</span></span><br><span class="line">        <span class="attr">multipass</span>: <span class="literal">true</span>, <span class="comment">// 類型：Boolean 預設：false 多次優化svg直到完全優化</span></span><br><span class="line">      &#125;)</span><br><span class="line">    )</span><br><span class="line">    .<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&quot;./blog&quot;</span>)); <span class="comment">//输出到blog文件夹</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 執行 gulp 命令時執行的任務</span></span><br><span class="line">gulp.<span class="title function_">task</span>(<span class="string">&quot;default&quot;</span>, gulp.<span class="title function_">parallel</span>(<span class="string">&quot;minify-images&quot;</span>));</span><br></pre></td></tr></table></figure><p>这种老的配置方法主要是任务执行时间比较短，反正也是白嫖，执行个一个小时也不为过？</p><p>那你可以替换为新版配置</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> gulp = <span class="built_in">require</span>(<span class="string">&#x27;gulp&#x27;</span>); <span class="comment">// 基础库</span></span><br><span class="line"><span class="keyword">const</span> imagemin = <span class="built_in">require</span>(<span class="string">&#x27;gulp-imagemin&#x27;</span>); <span class="comment">// 图片压缩</span></span><br><span class="line">	<span class="comment">// pngquant = require(&#x27;imagemin-pngquant&#x27;); // 深度压缩</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">default</span> = <span class="function">() =&gt;</span> (</span><br><span class="line">	gulp.<span class="title function_">src</span>(<span class="string">&#x27;src/images/*&#x27;</span>)</span><br><span class="line">		.<span class="title function_">pipe</span>(<span class="title function_">imagemin</span>())</span><br><span class="line">		.<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&#x27;dist/images&#x27;</span>))</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line"><span class="comment">// …</span></span><br><span class="line">.<span class="title function_">pipe</span>(<span class="title function_">imagemin</span>([</span><br><span class="line">	imagemin.<span class="title function_">gifsicle</span>(&#123;<span class="attr">interlaced</span>: <span class="literal">true</span>&#125;),</span><br><span class="line">	imagemin.<span class="title function_">mozjpeg</span>(&#123;<span class="attr">quality</span>: <span class="number">75</span>, <span class="attr">progressive</span>: <span class="literal">true</span>&#125;),</span><br><span class="line">	imagemin.<span class="title function_">optipng</span>(&#123;<span class="attr">optimizationLevel</span>: <span class="number">5</span>&#125;),</span><br><span class="line">	imagemin.<span class="title function_">svgo</span>(&#123;</span><br><span class="line">		<span class="attr">plugins</span>: [</span><br><span class="line">			&#123;<span class="attr">removeViewBox</span>: <span class="literal">true</span>&#125;, <span class="comment">// 移除svg的viewbox属性</span></span><br><span class="line">			&#123;<span class="attr">cleanupIDs</span>: <span class="literal">false</span>&#125;</span><br><span class="line">		]</span><br><span class="line">	&#125;)</span><br><span class="line">]))</span><br><span class="line"><span class="comment">// …</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// …</span></span><br><span class="line">.<span class="title function_">pipe</span>(<span class="title function_">imagemin</span>(&#123;</span><br><span class="line">	<span class="attr">interlaced</span>: <span class="literal">true</span>,</span><br><span class="line">	<span class="attr">progressive</span>: <span class="literal">true</span>,</span><br><span class="line">	<span class="attr">optimizationLevel</span>: <span class="number">5</span>,</span><br><span class="line">	<span class="attr">svgoPlugins</span>: [</span><br><span class="line">		&#123;</span><br><span class="line">			<span class="attr">removeViewBox</span>: <span class="literal">true</span></span><br><span class="line">		&#125;</span><br><span class="line">	]</span><br><span class="line">&#125;))</span><br><span class="line"><span class="comment">// …</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// …</span></span><br><span class="line">.<span class="title function_">pipe</span>(<span class="title function_">imagemin</span>([</span><br><span class="line">	imagemin.<span class="title function_">svgo</span>(&#123;</span><br><span class="line">		<span class="attr">plugins</span>: [</span><br><span class="line">			&#123;</span><br><span class="line">				<span class="attr">removeViewBox</span>: <span class="literal">true</span></span><br><span class="line">			&#125;</span><br><span class="line">		]</span><br><span class="line">	&#125;)</span><br><span class="line">], &#123;</span><br><span class="line">	<span class="attr">verbose</span>: <span class="literal">true</span></span><br><span class="line">&#125;))</span><br><span class="line"><span class="comment">// …</span></span><br></pre></td></tr></table></figure><p>请不要无脑复制，自行整合，开启关闭需要的，按照<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/sindresorhus/gulp-imagemin">官方配置</a>即可</p></div></details><details class="folding-tag" green><summary>自动转换配置部分</summary><div class="content"><h3 id="自动转换配置部分">自动转换配置部分<a class="fa-solid fa-hashtag" href="#自动转换配置部分"></a></h3><p>和自动压缩差不多，但我们说了，那是之前的解决方案，现在我们是要让博客使用 WebP，因此必须要向前看，自动转换为 WebP，同时 jsd 链接后缀也得自动改或者手动改，这我还在研究中</p><ul><li>其中图片使用<code>gulp imagemin</code>压缩</li><li>（之后考虑加入<code>WebP</code>转换 👍，<code>gulp</code>作者貌似不考虑适配，虽然<code>imagemin</code>测试成功了，但是还是等等再说）为什么这么说，已经配置了<code>gulpfile.js</code>，我不想再配置<code>imagemin.js</code>，少一个文件是一个文件</li></ul><p>还是用到了 gulp，所以 gulp<code>还是要装</code></p><p>配置差不多，用到的插件是</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save-dev gulp gulp-WebP</span><br></pre></td></tr></table></figure><p><code>gulpfile.js</code>配置如下</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> gulp = <span class="built_in">require</span>(<span class="string">&quot;gulp&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> <span class="title class_">WebP</span> = <span class="built_in">require</span>(<span class="string">&quot;gulp-WebP&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">exports</span>.<span class="property">default</span> = <span class="function">() =&gt;</span></span><br><span class="line">  gulp.<span class="title function_">src</span>(<span class="string">&quot;src/image.jpg&quot;</span>).<span class="title function_">pipe</span>(<span class="title class_">WebP</span>()).<span class="title function_">pipe</span>(gulp.<span class="title function_">dest</span>(<span class="string">&quot;dist&quot;</span>));</span><br></pre></td></tr></table></figure><p>至于怎么编写 actions 工作流文件，你应该会了</p><p>不过还是不能不考虑 imagemin 自己的插件，那是真好用</p><p>具体可查看<a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/imagemin">官方</a></p><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/imagemin/imagemin">https://github.com/imagemin/imagemin</a></p><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://github.com/imagemin/imagemin-gif2WebP">https://github.com/imagemin/imagemin-gif2WebP</a></p><p>如果是压缩 jpg,png,安装插件</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install imagemin imagemin-jpegtran imagemin-pngquant</span><br></pre></td></tr></table></figure><p>配置文件写在<code>imagemin.js</code>文件里面，说真的不错啊，命令是<code>node imagemin.js</code></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> imagemin = <span class="built_in">require</span>(<span class="string">&quot;imagemin&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> imageminJpegtran = <span class="built_in">require</span>(<span class="string">&quot;imagemin-jpegtran&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> imageminPngquant = <span class="built_in">require</span>(<span class="string">&quot;imagemin-pngquant&quot;</span>);</span><br><span class="line"></span><br><span class="line">(<span class="keyword">async</span> () =&gt; &#123;</span><br><span class="line">  <span class="keyword">const</span> files = <span class="keyword">await</span> <span class="title function_">imagemin</span>([<span class="string">&quot;images/*.&#123;jpg,png&#125;&quot;</span>], &#123;</span><br><span class="line">    <span class="attr">destination</span>: <span class="string">&quot;build/images&quot;</span>,</span><br><span class="line">    <span class="attr">plugins</span>: [</span><br><span class="line">      <span class="title function_">imageminJpegtran</span>(),</span><br><span class="line">      <span class="title function_">imageminPngquant</span>(&#123;</span><br><span class="line">        <span class="attr">quality</span>: [<span class="number">0.6</span>, <span class="number">0.8</span>],</span><br><span class="line">      &#125;),</span><br><span class="line">    ],</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(files);</span><br><span class="line">  <span class="comment">//=&gt; [&#123;data: &lt;Buffer 89 50 4e …&gt;, destinationPath: &#x27;build/images/foo.jpg&#x27;&#125;, …]</span></span><br><span class="line">&#125;)();</span><br></pre></td></tr></table></figure><p>但我们显然要转成 WebP，</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install imagemin imagemin-WebP</span><br></pre></td></tr></table></figure><p>具体配置如下，效果比较好</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> imageminWebP = <span class="built_in">require</span>(<span class="string">&quot;imagemin-WebP&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> <span class="title function_">convertPNGToWebP</span> = (<span class="params"></span>) =&gt;</span><br><span class="line">  <span class="title function_">imagemin</span>([<span class="title class_">PNGImages</span>], output, &#123;</span><br><span class="line">    <span class="attr">use</span>: [</span><br><span class="line">      <span class="title function_">imageminWebP</span>(&#123;</span><br><span class="line">        <span class="attr">quality</span>: <span class="number">85</span>,</span><br><span class="line">      &#125;),</span><br><span class="line">    ],</span><br><span class="line">  &#125;);</span><br><span class="line"><span class="keyword">const</span> <span class="title function_">convertJPGToWebP</span> = (<span class="params"></span>) =&gt;</span><br><span class="line">  <span class="title function_">imagemin</span>([<span class="title class_">JPGImages</span>], output, &#123;</span><br><span class="line">    <span class="attr">use</span>: [</span><br><span class="line">      <span class="title function_">imageminWebP</span>(&#123;</span><br><span class="line">        <span class="attr">quality</span>: <span class="number">75</span>,</span><br><span class="line">      &#125;),</span><br><span class="line">    ],</span><br><span class="line">  &#125;);</span><br><span class="line"><span class="title function_">optimiseJPEGImages</span>()</span><br><span class="line">  .<span class="title function_">then</span>(<span class="function">() =&gt;</span> <span class="title function_">optimisePNGImages</span>())</span><br><span class="line">  .<span class="title function_">then</span>(<span class="function">() =&gt;</span> <span class="title function_">convertPNGToWebP</span>())</span><br><span class="line">  .<span class="title function_">then</span>(<span class="function">() =&gt;</span> <span class="title function_">convertJPGToWebP</span>())</span><br><span class="line">  .<span class="title function_">catch</span>(<span class="function">(<span class="params">error</span>) =&gt;</span> <span class="variable language_">console</span>.<span class="title function_">log</span>(error));</span><br></pre></td></tr></table></figure><p>官方的话，给了一个区间</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> imagemin = <span class="built_in">require</span>(<span class="string">&quot;imagemin&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> imageminWebP = <span class="built_in">require</span>(<span class="string">&quot;imagemin-WebP&quot;</span>);</span><br><span class="line"></span><br><span class="line">(<span class="keyword">async</span> () =&gt; &#123;</span><br><span class="line">  <span class="keyword">await</span> <span class="title function_">imagemin</span>([<span class="string">&quot;images/*.&#123;jpg,png,WebP&#125;&quot;</span>], &#123;</span><br><span class="line">    <span class="attr">destination</span>: <span class="string">&quot;images&quot;</span>,</span><br><span class="line">    <span class="attr">plugins</span>: [<span class="title function_">imageminWebP</span>(&#123; <span class="attr">quality</span>: <span class="number">80</span> &#125;)],</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;Images optimized&quot;</span>);</span><br><span class="line">&#125;)();</span><br></pre></td></tr></table></figure><p>下面是 gif 转 WebP，我还没本地测试，不知道是否是能转成和 gif 差不多的动图而不是静态 WebP</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install --save imagemin imagemin-gif2WebP</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> imagemin = <span class="built_in">require</span>(<span class="string">&quot;imagemin&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> imageminGif2WebP = <span class="built_in">require</span>(<span class="string">&quot;imagemin-gif2WebP&quot;</span>);</span><br><span class="line"></span><br><span class="line">(<span class="keyword">async</span> () =&gt; &#123;</span><br><span class="line">  <span class="keyword">await</span> <span class="title function_">imagemin</span>([<span class="string">&quot;images/*.gif&quot;</span>], &#123;</span><br><span class="line">    <span class="attr">destination</span>: <span class="string">&quot;build/images&quot;</span>,</span><br><span class="line">    <span class="attr">plugins</span>: [<span class="title function_">imageminGif2WebP</span>(&#123; <span class="attr">quality</span>: <span class="number">50</span> &#125;)],</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;Images optimized&quot;</span>);</span><br><span class="line">&#125;)();</span><br></pre></td></tr></table></figure><p>或者也可以去官方仓库看看别的插件，配置用法，反正我觉得 imagemin 本身还是挺好用的（相比于 gulp）</p><p>这里是一个早期的例子，现在有些已经过时</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm i imagemin imagemin-giflossy imagemin-mozjpeg imagemin-pngquant imagemin-svgo imagemin-WebP</span><br></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 安装依赖:npm i imagemin imagemin-giflossy imagemin-mozjpeg imagemin-pngquant imagemin-svgo imagemin-WebP</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> fs = <span class="built_in">require</span>(<span class="string">&quot;fs&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> path = <span class="built_in">require</span>(<span class="string">&quot;path&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> imagemin = <span class="built_in">require</span>(<span class="string">&quot;imagemin&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> imageminMozjpeg = <span class="built_in">require</span>(<span class="string">&quot;imagemin-mozjpeg&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> imageminPngquant = <span class="built_in">require</span>(<span class="string">&quot;imagemin-pngquant&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> imageminGiflossy = <span class="built_in">require</span>(<span class="string">&quot;imagemin-giflossy&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> imageminWebP = <span class="built_in">require</span>(<span class="string">&quot;imagemin-WebP&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> imageminSvgo = <span class="built_in">require</span>(<span class="string">&quot;imagemin-svgo&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//stream pipeline</span></span><br><span class="line"><span class="keyword">const</span> util = <span class="built_in">require</span>(<span class="string">&quot;util&quot;</span>);</span><br><span class="line"><span class="keyword">const</span> stream = <span class="built_in">require</span>(<span class="string">&quot;stream&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> imgMIMEList = &#123;</span><br><span class="line">  <span class="attr">svg</span>: <span class="string">&quot;image/svg+xml&quot;</span>,</span><br><span class="line">  <span class="attr">png</span>: <span class="string">&quot;image/png&quot;</span>,</span><br><span class="line">  <span class="attr">jpg</span>: <span class="string">&quot;image/jpeg&quot;</span>,</span><br><span class="line">  <span class="attr">jpeg</span>: <span class="string">&quot;image/jpeg&quot;</span>,</span><br><span class="line">  <span class="attr">gif</span>: <span class="string">&quot;image/gif&quot;</span>,</span><br><span class="line">  <span class="attr">bmp</span>: <span class="string">&quot;image/bmp&quot;</span>,</span><br><span class="line">  <span class="title class_">WebP</span>: <span class="string">&quot;image/WebP&quot;</span>,</span><br><span class="line">  <span class="attr">ico</span>: <span class="string">&quot;image/x-icon&quot;</span>,</span><br><span class="line">  <span class="attr">tif</span>: <span class="string">&quot;image/tiff&quot;</span>,</span><br><span class="line">  <span class="attr">psd</span>: <span class="string">&quot;application/octet-stream&quot;</span>,</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">//<span class="doctag">TODO:</span>提示压缩率</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="title function_">fn_imagemin</span> = <span class="keyword">async</span> (<span class="params">ctx, next</span>) =&gt; &#123;</span><br><span class="line">  <span class="keyword">const</span> file = ctx.<span class="property">request</span>.<span class="property">files</span>.<span class="property">file</span>; <span class="comment">// 获取上传文件</span></span><br><span class="line">  <span class="keyword">const</span> reader = fs.<span class="title function_">createReadStream</span>(file.<span class="property">path</span>); <span class="comment">// 创建可读流</span></span><br><span class="line">  <span class="keyword">const</span> ext = file.<span class="property">name</span>.<span class="title function_">split</span>(<span class="string">&quot;.&quot;</span>).<span class="title function_">pop</span>(); <span class="comment">// 获取上传文件扩展名</span></span><br><span class="line">  <span class="keyword">const</span> dataMIME = <span class="string">&quot;data:&quot;</span> + imgMIMEList[ext] + <span class="string">&quot;;base64,&quot;</span>; <span class="comment">//根据扩展名设定媒体类型</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> imgName = <span class="title function_">getRandomId</span>() + <span class="string">&quot;.&quot;</span> + ext; <span class="comment">//压缩图片文件名</span></span><br><span class="line">  <span class="keyword">const</span> imgSourcePath = <span class="string">`storage/upload/img`</span>; <span class="comment">//压缩源图片文件夹</span></span><br><span class="line">  <span class="keyword">const</span> imgResultPath = <span class="string">`storage/result/img`</span>; <span class="comment">//压缩目标文件夹</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> imgSourcePathFile = <span class="string">`<span class="subst">$&#123;imgSourcePath&#125;</span>/<span class="subst">$&#123;imgName&#125;</span>`</span>; <span class="comment">//压缩源图片路径</span></span><br><span class="line">  <span class="keyword">const</span> imgSourcePathFileCWD = path.<span class="title function_">resolve</span>(process.<span class="title function_">cwd</span>(), imgSourcePathFile); <span class="comment">//压缩源图片绝对路径</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> imgSourcePathCWD = path.<span class="title function_">resolve</span>(process.<span class="title function_">cwd</span>(), imgSourcePath); <span class="comment">//源文件夹绝对路径</span></span><br><span class="line">  <span class="keyword">const</span> imgResultPathCWD = path.<span class="title function_">resolve</span>(process.<span class="title function_">cwd</span>(), imgResultPath); <span class="comment">//目标文件夹绝对路径</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> upStream = fs.<span class="title function_">createWriteStream</span>(imgSourcePathFileCWD); <span class="comment">// 创建可写流 存储源图片</span></span><br><span class="line">  <span class="comment">// reader.pipe(upStream);// 可读流通过管道写入可写流</span></span><br><span class="line">  <span class="keyword">const</span> pipeline = util.<span class="title function_">promisify</span>(stream.<span class="property">pipeline</span>);</span><br><span class="line">  <span class="keyword">let</span> resultData = <span class="literal">null</span>;</span><br><span class="line">  <span class="keyword">await</span> <span class="title function_">pipeline</span>(reader, upStream);</span><br><span class="line">  <span class="keyword">await</span> <span class="title function_">imageCompress</span>(imgSourcePathFile, imgResultPath, <span class="function">(<span class="params">imgBuffer</span>) =&gt;</span> &#123;</span><br><span class="line">    resultData = dataMIME + imgBuffer.<span class="title function_">toString</span>(<span class="string">&quot;base64&quot;</span>);</span><br><span class="line">  &#125;).<span class="title function_">catch</span>(<span class="function">(<span class="params">err</span>) =&gt;</span> &#123;</span><br><span class="line">    ctx.<span class="property">response</span>.<span class="property">status</span> = <span class="number">201</span>;</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="comment">//删除图片</span></span><br><span class="line">  <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="title function_">deleteFile</span>(imgSourcePathCWD, imgName);</span><br><span class="line">    <span class="title function_">deleteFile</span>(imgResultPathCWD, imgName);</span><br><span class="line">  &#125;, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (file) &#123;</span><br><span class="line">    ctx.<span class="property">response</span>.<span class="property">body</span> = resultData;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    ctx.<span class="property">response</span>.<span class="property">status</span> = <span class="number">204</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 压缩图片</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">String</span>&#125; <span class="variable">sourcePath</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">String</span>&#125; <span class="variable">resultPath</span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span> &#123;<span class="type">Function</span>&#125; <span class="variable">callback</span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">function</span> <span class="title function_">imageCompress</span>(<span class="params">sourcePath, resultPath, callback</span>) &#123;</span><br><span class="line">  <span class="keyword">const</span> files = <span class="keyword">await</span> <span class="title function_">imagemin</span>([sourcePath], &#123;</span><br><span class="line">    <span class="attr">destination</span>: resultPath,</span><br><span class="line">    <span class="attr">plugins</span>: [</span><br><span class="line">      <span class="title function_">imageminMozjpeg</span>(&#123;</span><br><span class="line">        <span class="attr">quality</span>: <span class="number">70</span>,</span><br><span class="line">      &#125;),</span><br><span class="line">      <span class="title function_">imageminPngquant</span>(),</span><br><span class="line">      <span class="title function_">imageminGiflossy</span>(&#123;</span><br><span class="line">        <span class="attr">lossy</span>: <span class="number">80</span>,</span><br><span class="line">      &#125;),</span><br><span class="line">      <span class="title function_">imageminWebP</span>(),</span><br><span class="line">      <span class="title function_">imageminSvgo</span>(),</span><br><span class="line">    ],</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> imgBuffer = files[<span class="number">0</span>].<span class="property">data</span>;</span><br><span class="line">  <span class="title function_">callback</span>(imgBuffer);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 获取随机id</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">getRandomId</span>(<span class="params"></span>) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="title class_">Math</span>.<span class="title function_">random</span>().<span class="title function_">toString</span>(<span class="number">36</span>).<span class="title function_">substr</span>(<span class="number">2</span>) + <span class="title class_">Date</span>.<span class="title function_">now</span>().<span class="title function_">toString</span>(<span class="number">36</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 删除某一个包下面的需要符合格式的文件。</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span>  &#123;<span class="type">String</span>&#125; url  文件路径，绝对路径</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param</span>  &#123;<span class="type">String</span>&#125; name 需要删除的文件名称</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return</span> &#123;<span class="type">Null</span>&#125;</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> huangh 20170123</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">deleteFile</span>(<span class="params">url, name</span>) &#123;</span><br><span class="line">  <span class="keyword">let</span> files = [];</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (fs.<span class="title function_">existsSync</span>(url)) &#123;</span><br><span class="line">    <span class="comment">//判断给定的路径是否存在</span></span><br><span class="line"></span><br><span class="line">    files = fs.<span class="title function_">readdirSync</span>(url); <span class="comment">//返回文件和子目录的数组</span></span><br><span class="line"></span><br><span class="line">    files.<span class="title function_">forEach</span>(<span class="keyword">function</span> (<span class="params">file, index</span>) &#123;</span><br><span class="line">      <span class="keyword">let</span> curPath = path.<span class="title function_">join</span>(url, file);</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (fs.<span class="title function_">statSync</span>(curPath).<span class="title function_">isDirectory</span>()) &#123;</span><br><span class="line">        <span class="comment">//同步读取文件夹文件，如果是文件夹，则函数回调</span></span><br><span class="line">        <span class="title function_">deleteFile</span>(curPath, name);</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">if</span> (file.<span class="title function_">indexOf</span>(name) &gt; -<span class="number">1</span>) &#123;</span><br><span class="line">          <span class="comment">//是指定文件，则删除</span></span><br><span class="line">          fs.<span class="title function_">unlinkSync</span>(curPath);</span><br><span class="line">          <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;删除文件：&quot;</span> + curPath);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;给定的路径不存在！&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="variable language_">module</span>.<span class="property">exports</span> = &#123;</span><br><span class="line">  <span class="string">&quot;POST /upload/img&quot;</span>: fn_imagemin,</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure></div></details><p>我们原来还在顾忌 WebP 的支持问题，考虑自适应，加入判断，又拍云，<a target="_blank" rel="noopener external nofollow noreferrer" href="https://WebP.sh/">https://WebP.sh/</a> 也提供这样的功能，但现在我的态度是，你看不到我博客的图片是你我无缘</p><h2 id="视频（题外话）">视频（题外话）<a class="fa-solid fa-hashtag" href="#视频（题外话）"></a></h2><div class="tabs" id="视频"><ul class="nav-tabs no-default"><button type="button" class="tab" data-href="视频-1">鸡霸网盘2号</button><button type="button" class="tab" data-href="视频-2">Teambition</button><button type="button" class="tab" data-href="视频-3">OneManager</button></ul><div class="tab-contents"><div class="tab-item-content" id="视频-1"><h3 id="鸡霸网盘-2-号"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://file.nmb.show/">鸡霸网盘 2 号</a><a class="fa-solid fa-hashtag" href="#鸡霸网盘-2-号"></a></h3><p>视频文件小于 300M，免审核</p><p><a href="https://blog.ccknbc.cc/music/">预览</a></p></div><div class="tab-item-content" id="视频-2"><h3 id="Teambition"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.teambition.com/">Teambition</a><a class="fa-solid fa-hashtag" href="#Teambition"></a></h3><p>当阿里这个免费的办公协同工具诞生，我们在上传大文件视频进入播放页拿到 API 调用地址即可，不限速，临时使用（几天后地址会失效，或许有大神，蹲 API）</p></div><div class="tab-item-content" id="视频-3"><h3 id="OneManager"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://od.ccknbc.cc/">OneManager</a><a class="fa-solid fa-hashtag" href="#OneManager"></a></h3><p>实际上就是利用微软的<code>OneDrive</code>，如果你也配置了话，不如试试，实际访问速度还是取决于当地运营商</p><p><a href="https://blog.ccknbc.cc/bkpp/live/">预览</a></p></div></div><div class="tab-to-top"><button type="button" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div></div><h2 id="关联阅读">关联阅读<a class="fa-solid fa-hashtag" href="#关联阅读"></a></h2><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://tangshuang.gitbooks.io/gulp-chinese-guide/content/">Gulp 中文文档</a></p><p><a target="_blank" rel="noopener external nofollow noreferrer" href="https://segmentfault.com/a/1190000018392559">Web 性能优化： 图片优化让网站大小减少 62%</a></p><h2 id="CDN-解决方案">CDN 解决方案<a class="fa-solid fa-hashtag" href="#CDN-解决方案"></a></h2><p>拿又拍云来说，<a target="_blank" rel="noopener external nofollow noreferrer" href="https://help.upyun.com/knowledge-base/image/">图像处理，URL 作图</a> 是个不错的解决方案</p></article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta"><i class="fas fa-circle-user fa-fw"></i>文章作者: </span><span class="post-copyright-info"><a href="https://blog.ccknbc.cc/">CC康纳百川</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta"><i class="fas fa-square-arrow-up-right fa-fw"></i>文章链接: </span><span class="post-copyright-info"><a href="https://blog.ccknbc.cc/posts/the-webp-road-of-blog-pictures/">https://blog.ccknbc.cc/posts/the-webp-road-of-blog-pictures/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta"><i class="fas fa-circle-exclamation fa-fw"></i>版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"><i style="color:#8fbc8f" class="fa-brands fa-creative-commons"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-by"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-nc"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-sa"></i> CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://blog.ccknbc.cc">CC的部落格</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%E5%8D%9A%E5%AE%A2/">博客</a></div><div class="post_share"><div class="social-share" data-image="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/a4d78fbe1ca6e99e19535a095681c5ba_w1920_h1080_s770.jpg" data-sites="wechat,weibo,qq,facebook,twitter"></div><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload='this.media="all"'><script src="https://jsd.cdn.zzko.cn/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i>赞赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://www.rocschool.com/tool/qr/qr/id/51.html" rel="external nofollow noreferrer" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/qr.png" alt="三合一"></a><div class="post-qr-code-desc">三合一</div></li><li class="reward-item"><a href="https://afdian.net/@ccknbc" rel="external nofollow noreferrer" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/afdian.png" alt="爱发电"></a><div class="post-qr-code-desc">爱发电</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/posts/i-dont-really-want-html/" title="我真的不想要 .html"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/0601aa76f5eff82efcafd3450db0da8c_w2240_h1260_s822.jpg" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/friend_404.gif"' alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">我真的不想要 .html</div></div></a></div><div class="next-post pull-right"><a href="/posts/special-test-article/" title="语雀专用测试文章"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/aecae1b395722cc3655d86a55749a8f7_w1280_h720_s706.jpg" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/friend_404.gif"' alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">语雀专用测试文章</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/posts/hexo-webpushr-notification/" title="Hexo浏览器定向推送文章更新"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/d2a947d48815ed24936a919873b97841_w1366_h768_s31.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-10-05</div><div class="title">Hexo浏览器定向推送文章更新</div></div></a></div><div><a href="/posts/yuque-to-hexo/" title="语雀文章同步至Hexo笔记"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/721e476cb2661152b9c43621c94e3ed7_w1366_h768_s86.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-10-04</div><div class="title">语雀文章同步至Hexo笔记</div></div></a></div><div><a href="/posts/how-to-hide-hexo-articles-gracefully/" title="如何优雅隐藏 Hexo 文章"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/aa5ebc0731a66fa5fb73df76da759ae3_w1920_h1080_s557.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-10-22</div><div class="title">如何优雅隐藏 Hexo 文章</div></div></a></div><div><a href="/posts/google-adsense-configuration-manual/" title="Google Adsense 配置手册"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/0a77436f677dd11422579e07ba6423b3_w1920_h1080_s188.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-10-24</div><div class="title">Google Adsense 配置手册</div></div></a></div><div><a href="/posts/introduction-of-plugin-tags-based-on-butterfly/" title="Hexo标签笔记"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/666ccfeb387717d69a0e3333cc1170dc_w1004_h591_s48.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-03-05</div><div class="title">Hexo标签笔记</div></div></a></div><div><a href="/posts/hexo-toss/" title="HEXO 折腾"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/45d888bd81b86777b3364e4a16ff72c6_w2240_h1260_s476.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2020-07-01</div><div class="title">HEXO 折腾</div></div></a></div></div></div><hr class="custom-hr"><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="waline-wrap"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#WebP-%E8%BD%AC%E6%8D%A2"><span class="toc-number">1.</span> <span class="toc-text">WebP 转换</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%99%BA%E5%9B%BE"><span class="toc-number">1.1.</span> <span class="toc-text">智图</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WebP2jpg-online"><span class="toc-number">1.2.</span> <span class="toc-text">WebP2jpg-online</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Gitee-Pages%EF%BC%88%E5%9B%BD%E5%86%85%E8%AE%BF%E9%97%AE%E8%89%AF%E5%A5%BD%EF%BC%89"><span class="toc-number">1.2.1.</span> <span class="toc-text">Gitee Pages（国内访问良好）</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#GitHub-Pages"><span class="toc-number">1.2.2.</span> <span class="toc-text">GitHub Pages</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#WebP-%E5%9B%BE%E7%89%87%E6%A0%BC%E5%BC%8F%E7%9A%84%E5%8F%91%E5%B1%95%E8%B6%8B%E5%8A%BF-%E5%8F%88%E6%8B%8D%E4%BA%91"><span class="toc-number">1.3.</span> <span class="toc-text">WebP - 图片格式的发展趋势 - 又拍云</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#GIF-%E5%88%B0-WEBP-%E8%BD%AC%E6%8D%A2%E5%99%A8"><span class="toc-number">1.4.</span> <span class="toc-text">GIF 到 WEBP 转换器</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9B%BE%E5%BA%8A"><span class="toc-number">2.</span> <span class="toc-text">图床</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B5%81%E6%B5%AA%E5%9B%BE%E5%BA%8A"><span class="toc-number">2.1.</span> <span class="toc-text">流浪图床</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%B8%A1%E9%9C%B8%E5%9B%BE%E5%BA%8A"><span class="toc-number">2.2.</span> <span class="toc-text">鸡霸图床</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%B8%A1%E9%9C%B8%E7%BD%91%E7%9B%98"><span class="toc-number">2.3.</span> <span class="toc-text">鸡霸网盘</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#IMG-WANG"><span class="toc-number">2.4.</span> <span class="toc-text">IMG.WANG</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#OneManager"><span class="toc-number">2.5.</span> <span class="toc-text">OneManager</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E5%8C%96"><span class="toc-number">3.</span> <span class="toc-text">自动化</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%96%B9%E6%A1%88"><span class="toc-number">3.1.</span> <span class="toc-text">方案</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%87%86%E5%A4%87"><span class="toc-number">3.2.</span> <span class="toc-text">准备</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#PNG-JPG-GIF"><span class="toc-number">3.3.</span> <span class="toc-text">PNG JPG GIF</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E5%90%88%E5%B9%B6%E9%85%8D%E7%BD%AE%E9%83%A8%E5%88%86"><span class="toc-number">3.4.</span> <span class="toc-text">自动合并配置部分</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E5%8E%8B%E7%BC%A9%E9%85%8D%E7%BD%AE%E9%83%A8%E5%88%86"><span class="toc-number">3.5.</span> <span class="toc-text">自动压缩配置部分</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%87%AA%E5%8A%A8%E8%BD%AC%E6%8D%A2%E9%85%8D%E7%BD%AE%E9%83%A8%E5%88%86"><span class="toc-number">3.6.</span> <span class="toc-text">自动转换配置部分</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A7%86%E9%A2%91%EF%BC%88%E9%A2%98%E5%A4%96%E8%AF%9D%EF%BC%89"><span class="toc-number">4.</span> <span class="toc-text">视频（题外话）</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%B8%A1%E9%9C%B8%E7%BD%91%E7%9B%98-2-%E5%8F%B7"><span class="toc-number">4.1.</span> <span class="toc-text">鸡霸网盘 2 号</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Teambition"><span class="toc-number">4.2.</span> <span class="toc-text">Teambition</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#OneManager"><span class="toc-number">4.3.</span> <span class="toc-text">OneManager</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%B3%E8%81%94%E9%98%85%E8%AF%BB"><span class="toc-number">5.</span> <span class="toc-text">关联阅读</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#CDN-%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88"><span class="toc-number">6.</span> <span class="toc-text">CDN 解决方案</span></a></li></ol></div></div></div></div></main><footer id="footer" style="background:linear-gradient(135deg,#fff1eb,#ace0f9)"><div id="footer-wrap"><div class="icp"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://beian.miit.gov.cn"><img class="icp-icon" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/icp.png" alt="ICP"><span>鄂 ICP 备 2020019764 号</span></a></div><div class="gongan"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.beian.gov.cn/portal/registerSystemInfo?recordcode=42088102000092"><img class="gongan-icon" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/gongan.png" alt="gongan"><span>鄂公网安备 42088102000092 号</span></a></div><div class="live"><span>本站已运行</span><span id="display_live"></span><span class="moe-text">CCKNBC All Rights Reserved.</span><script>function blog_live(){window.setTimeout(blog_live,1e3);var e=new Date("2020-06-04T00:00:00"),o=new Date,l=o.getFullYear(),o=o.getTime()-e.getTime(),e=864e5,t=365*e,i=Math.floor(o/t),t=Math.floor(o%t/e),e=Math.floor(o%e/60/60/1e3),a=Math.floor(o%36e5/60/1e3),o=Math.floor(o%6e4/1e3);display_live.innerHTML=" "+i+" 年 "+t+" 天 "+e+" 小时 "+a+" 分 "+o+" 秒<br>&copy; 2020 - "+l+" "}blog_live()</script></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><a class="edit-yuque" target="_blank" rel="noopener external nofollow noreferrer" href="https://www.yuque.com/ccknbc/blog/15/edit/" title="在语雀上以富文本格式编辑/预览 - 博客图片的 WebP 之路"><i class="fa-solid fa-crow"></i></a><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fa-solid fa-arrows-alt-h"></i></button><button id="readmode" type="button" title="阅读模式"><i class="fa-solid fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fa-solid fa-adjust"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="设置"><i class="fa-solid fa-cog"></i></button><button id="share-link" type="button" title="分享链接"><i class="fa-solid fa-share"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fa-solid fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fa-solid fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fa-solid fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://jsd.cdn.zzko.cn/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.js"></script><script src="https://jsd.cdn.zzko.cn/npm/instant.page/instantpage.js" type="module"></script><script src="https://jsd.cdn.zzko.cn/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://jsd.cdn.zzko.cn/npm/node-snackbar/dist/snackbar.min.js"></script><div class="js-pjax"><script>(()=>{var e=()=>{var e;const t=document.querySelectorAll("#article-container .mermaid-wrap");0!==t.length&&(e=()=>{{var e=t;window.loadMermaid=!0;const a="dark"===document.documentElement.getAttribute("data-theme")?"dark":"default";Array.from(e).forEach((e,t)=>{const n=e.firstElementChild;e="%%{init:{ 'theme':'"+a+"'}}%%\n"+n.textContent;const d=mermaid.render("mermaid-"+t,e);"string"==typeof d?(t=d,n.insertAdjacentHTML("afterend",t)):d.then(({svg:e})=>{n.insertAdjacentHTML("afterend",e)})})}},btf.addGlobalFn("themeChange",e,"mermaid"),window.loadMermaid?e():btf.getScript("https://jsd.cdn.zzko.cn/npm/mermaid/dist/mermaid.min.js").then(e))};btf.addGlobalFn("encrypt",e,"mermaid"),window.pjax?e():document.addEventListener("DOMContentLoaded",e)})()</script><script>(()=>{let n=window.walineFn||null;const t=e=>{const n=e(Object.assign({el:"#waline-wrap",serverURL:"https://waline.ccknbc.cc",pageview:!1,dark:'html[data-theme="dark"]',path:window.location.pathname,comment:!1,imageUploader:function(e){var n=new FormData,t=new Headers;return n.append("file",e),n.append("album_id","10"),n.append("permission","0"),t.append("Authorization","Bearer 24|o8Crl5y0oK3luyUs17fBxDtAcevk1iiLHVFMNjpA"),t.append("Accept","application/json"),fetch("https://wmimg.com/api/v1/upload",{method:"POST",headers:t,body:n}).then(e=>e.json()).then(e=>e.data.links.url)}},{pageSize:10,meta:["nick","mail","link"],requiredMeta:["nick","mail"],login:"force",copyright:!0,search:!0,turnstileKey:"0x4AAAAAAAECBl27OB5SZrQT",locale:{admin:"博主",sofa:"这里冷冷清清的，快来留下脚印吧！",placeholder:"根据《互联网跟帖评论服务管理规定》，将展示您的归属地，并开启强制注册登录后才允许评论\n社交登录现已支持【QQ Weibo GitHub X Facebook】等平台，登录后可点击头像更改个人主页地址，方便CC串门\n在评论框粘贴图片，自动上传至图床，请不要将评论区作为您的图床，更不要上传违法图片，谢谢合作",reactionTitle:"就现在，表明你的态度！",reaction0:"鼓励",reaction1:"菜狗",reaction2:"正确",reaction3:"错误",reaction4:"思考",reaction5:"无聊",level0:"买菜",level1:"切菜",level2:"炒菜",level3:"煲汤",level4:"煮面",level5:"上桌",level6:"开吃"},emoji:["https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/"],reaction:["https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/鼓掌.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/菜狗.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/正确.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/错误.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/思考.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/睡觉.png"]}));btf.addGlobalFn("pjax",()=>{n.destroy()},"destroyWaline")};var e=()=>{n?t(n):(btf.getCSS("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline.css"),btf.getCSS("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline-meta.css").then(()=>import("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline.js")).then(({init:e})=>{n=e||Waline.init,t(n),window.walineFn=n}))};btf.loadComment(document.getElementById("waline-wrap"),e)})()</script></div><script>window.addEventListener("load",()=>{const t=e=>e=""!==e&&150<(e=(e=(e=(e=e.replace(/<img.*?src="(.*?)"?[^\>]+>/gi,"[图片]")).replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi,"[链接]")).replace(/<pre><code>.*?<\/pre>/gi,"[代码]")).replace(/<[^>]+>/g,"")).length?e.substring(0,150)+"...":e,a=t=>{let a="";if(t.length)for(let e=0;e<t.length;e++)a=(a+="<div class='aside-list-item'>")+`<div class='content'>
        <a class='comment' href='${t[e].url}' title='${t[e].content}'>${t[e].content}</a>
        <div class='name'><span>${t[e].nick} / </span><time datetime="${t[e].date}">${btf.diffDate(t[e].date,!0)}</time></div>
        </div></div>`;else a+="没有评论";var e=document.querySelector("#card-newest-comments .aside-list");e&&(e.innerHTML=a),window.lazyLoadInstance&&window.lazyLoadInstance.update(),window.pjax&&window.pjax.refresh(e)};var e=()=>{var e;document.querySelector("#card-newest-comments .aside-list")&&((e=btf.saveToLocal.get("waline-newest-comments"))?a(JSON.parse(e)):(async()=>{try{var e=(await(await fetch("https://waline.ccknbc.cc/api/comment?type=recent&count=3",{method:"GET"})).json()).data.map(e=>({content:t(e.comment),avatar:e.avatar,nick:e.nick,url:e.url+"#post-comment",date:e.time||e.insertedAt}));btf.saveToLocal.set("waline-newest-comments",JSON.stringify(e),10/1440),a(e)}catch(e){console.error(e),document.querySelector("#card-newest-comments .aside-list").textContent="无法获取评论，请确认相关配置是否正确"}})())};e(),btf.addGlobalFn("pjaxComplete",e,"waline_newestComment")})</script><script defer src="/js/custom.js"></script><script src="https://jsd.cdn.zzko.cn/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors=["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"];var pjax=new Pjax({elements:'a:not([target="_blank"])',selectors:pjaxSelectors,cacheBust:!1,analytics:!1,scrollRestoration:!1});const triggerPjaxFn=e=>{e&&Object.values(e).forEach(e=>{e()})};document.addEventListener("pjax:send",function(){btf.removeGlobalFnEvent("pjax"),btf.removeGlobalFnEvent("themeChange");var e=document.body.classList;e.contains("read-mode")&&e.remove("read-mode"),triggerPjaxFn(window.globalFn.pjaxSend)}),document.addEventListener("pjax:complete",()=>{document.querySelectorAll("script[data-pjax]").forEach(e=>{const t=document.createElement("script");var a=e.text||e.textContent||e.innerHTML||"";Array.from(e.attributes).forEach(e=>t.setAttribute(e.name,e.value)),t.appendChild(document.createTextNode(a)),e.parentNode.replaceChild(t,e)}),triggerPjaxFn(window.globalFn.pjaxComplete)}),document.addEventListener("pjax:error",e=>{404===e.request.status&&pjax.loadUrl("/404")})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div class="docsearch-wrap"><div id="docsearch" style="display:none"></div><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@docsearch/css/dist/style.css"><script src="https://jsd.cdn.zzko.cn/npm/@docsearch/js/dist/umd/index.js"></script><script>(()=>{docsearch(Object.assign({appId:"97MUPN4DMC",apiKey:"a003a39f337f5186ec11f5f92bae62b3",indexName:"ccknbc",container:"#docsearch"},{placeholder:"Ctrl/⌘ + K 唤醒搜索服务",maxResultsPerGroup:7,translations:{button:{buttonText:"搜索",buttonAriaLabel:"搜索"},modal:{searchBox:{resetButtonTitle:"清空",resetButtonAriaLabel:"清空",cancelButtonText:"取消",cancelButtonAriaLabel:"取消"},startScreen:{recentSearchesTitle:"最近搜索历史",noRecentSearchesText:"搜索历史为空",saveRecentSearchButtonTitle:"保存搜索记录",removeRecentSearchButtonTitle:"清除搜索记录",favoriteSearchesTitle:"收藏夹",removeFavoriteSearchButtonTitle:"移出收藏夹"},errorScreen:{titleText:"未能获取搜索结果",helpText:"您可能需要检查您的网络连接"},footer:{selectText:"选择",selectKeyAriaLabel:"回车键",navigateText:"切换",navigateUpKeyAriaLabel:"方向键上",navigateDownKeyAriaLabel:"方向键下",closeText:"关闭",closeKeyAriaLabel:"退出键",searchByText:"搜索服务提供: DocSearch by"},noResultsScreen:{noResultsText:"未搜索到相关内容",suggestedQueryText:"您可尝试搜索",reportMissingResultsText:"确认搜索结果是正确的？",reportMissingResultsLinkText:"反馈给Algolia"}}}}));const e=()=>{document.querySelector(".DocSearch-Button").click()};var t=()=>{btf.addEventListenerPjax(document.querySelector("#search-button > .search"),"click",e)};t(),window.addEventListener("pjax:complete",t)})()</script></div></div><script>const copyright_enable=!0</script><script src="https://jsd.cdn.zzko.cn/npm/turndown/dist/turndown.min.js"></script><script src="https://jsd.cdn.zzko.cn/gh/ccknbc-forked/hexo-butterfly-copymarkdown/lib/copyMarkdown.min.js"></script><script src="https://jsd.cdn.zzko.cn/gh/ccknbc-forked/hexo-butterfly-copymarkdown/lib/reprint.min.js"></script><script>(function (w, d, s, id) {
        if (typeof (w.webpushr) !== 'undefined') return;
        w.webpushr = w.webpushr || function () { (w.webpushr.q = w.webpushr.q || []).push(arguments) };
        var js, fjs = d.getElementsByTagName(s)[0];
        js = d.createElement(s);
        js.id = id;
        js.async = 1;
        js.src = "https://cdn.webpushr.com/app.min.js";
        fjs.parentNode.appendChild(js);
        }(window, document, 'script', 'webpushr-jssdk'));

        webpushr('setup', {
        'key': 'BB9Y-w9p3u0CKA7UP9nupB6I-_NqE2MuODmKJjyC4W2YflX06Ff_hEhrNJfonrut5l6gCa28gC83q2OII7Qv-oA',
        'sw': 'none'
        });
        </script></body></html>